/*
    多线程质数运算
*/

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>

typedef struct num
{
    int a;
    int b;
    struct timeval time;
}num;

int is_prime(int n) {
    if(n == 1)  return 0;
    int flag = 1;
    for(unsigned long i = 2; i *i <= n; i++)
    {
        if(n%i==0)
        {
            flag = 0;
            break;
        }
    }
    return flag;
}

void* routine(void* argc)
{
    int count = 0;
    num* n = (num*)argc;
    for(int i = n->a; i <= n->b; i++)
    {
        count += is_prime(i);
    }
    struct timeval end;
    gettimeofday(&end, NULL);
    printf("%ld : %d 到 %d 一共有 %d个质数,所用时间 %ld s\n", pthread_self(), n->a, n->b, count, end.tv_sec - n->time.tv_sec);
}

int main(int argc, char* argv[])
{
    // CPU 核心数 
    // sysconf(_SC_NPROCESSORS_CONF)
    // 系统可用的核心数
    int core = sysconf(_SC_NPROCESSORS_ONLN);
    printf("core:%d\n", core);

    // 读取命令行参数转化为整型值
    int size = atoi(argv[1]);
    pthread_t tid[size];
    
    num r[size];
    //增量式迭代法，防止循环代码冗余
    int part = 100000000/size;
    for(int i = 0; i < size; i++)
    {
        r[i].a = 1 + part*i;    // 1
        r[i].b = (i+1)*part;    // 
        gettimeofday(&r[i].time, NULL);
        printf("%9d~%9d\n", r[i].a, r[i].b);
        pthread_create(&tid[i], NULL, routine, &r[i]);
    }
    for(int i = 0; i<size; i++)
    {
        //会阻塞所以不能和create放在一个循环中
        pthread_join(tid[i], NULL);
    }
    return 0;
}